Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b0e8ea9-7fd3-4e74-87d7-c3b7e69d8a7b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b0e8ea9-7fd3-4e74-87d7-c3b7e69d8a7b
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Membership snapshots, incomplete permission sources, and pending invitations currently undermine fail-closed reconciliation.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (3)
What changed in this PR
Adds a backend for managing direct, role-aware GitHub repository access.
Changes:
- Loads validated repository role files.
- Reconciles direct grants through GraphQL and REST.
- Adds comprehensive tests and rollout documentation.
| File | Description |
|---|---|
README.md |
Documents configuration and rollout. |
lib/entitlements/backend/github_repository.rb |
Defines and loads the backend. |
lib/entitlements/backend/github_repository/configuration.rb |
Validates and loads role files. |
lib/entitlements/backend/github_repository/controller.rb |
Coordinates reconciliation. |
lib/entitlements/backend/github_repository/models/repository_access.rb |
Models role-aware access. |
lib/entitlements/backend/github_repository/provider.rb |
Calculates repository changes. |
lib/entitlements/backend/github_repository/service.rb |
Implements GitHub reads and mutations. |
spec/unit/entitlements/backend/github_repository_spec.rb |
Tests backend behavior. |
spec/unit/spec_helper.rb |
Loads the backend in tests. |
spec/unit/fixtures/repositories/other.repo/maintain.txt |
Adds group-rule fixture. |
spec/unit/fixtures/repositories/other.repo/admin.yaml |
Adds expired-rule fixture. |
spec/unit/fixtures/repositories/entitlements-app/write.rb |
Adds Ruby-rule fixture. |
spec/unit/fixtures/repositories/entitlements-app/triage.yaml |
Adds YAML-rule fixture. |
spec/unit/fixtures/repositories/entitlements-app/read.txt |
Adds text-rule fixture. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| def apply(repository, instructions) | ||
| Configuration.validate_repository!(repository) | ||
| instructions.sort_by { |instruction| [instruction.fetch(:action) == :upsert ? 0 : 1, instruction.fetch(:login).downcase] }.each do |instruction| |
| if status == 201 | ||
| unless result.is_a?(Sawyer::Resource) && result[:id].is_a?(Integer) && result[:id] > 0 | ||
| GitHubRepository.fail!("Malformed repository invitation response") | ||
| end | ||
| Entitlements.logger.warn("#{repository}: invitation created for #{instruction.fetch(:login)}; access is not yet active") | ||
| end |
| unless edge.is_a?(Hash) && edge["node"].is_a?(Hash) && edge["permissionSources"].is_a?(Array) | ||
| GitHubRepository.fail!("Missing or malformed repository permission sources") | ||
| end |
|
The vendored-gem demo is available in github/entitlements#142229 (draft, DO NOT MERGE). It pins preview version |
The live entitlements-default demo proved edge.permission adds a public_repo scope requirement to an admin:org token. Read only the source-specific roles consumed by reconciliation, without broadening credentials or falling back to effective permissions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b0e8ea9-7fd3-4e74-87d7-c3b7e69d8a7b
|
The real github/entitlements#142229 no-op calculation exposed an unnecessary credential requirement in the initial query: effective edge.permission requires public_repo, while CI has admin:org. Commit d12e39a removes that unused field, retaining exact direct permissionSources.roleName and strict error handling. No token scopes were broadened. A regression test guards the requested fields; all 285 plugin examples pass with 100% line coverage. The demo now vendors the refreshed source-commit-derived gem and is rerunning the actual entitlements-default calculation. No live mutations or merge are involved. |
Remove all repository team associations and undeclared direct grants, including outside collaborators. Preserve team hierarchy and membership, order user upserts before cleanup, and verify snapshots before and after application. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8107bce-2500-45f8-b046-3f50092d9fbd
|
Published individual-only repository reconciliation in The live read-only App no-op run succeeded and now proposes removal of Production gate discovered: the declared user currently has organization-owner JIT access and the backend rejects desired owners. The demo uses the existing warn-and-skip setting to verify team cleanup, not as a production fix. Owner declarations/direct-grant persistence during JIT elevation need an explicit policy and API validation before rollout. This live run does not verify owner grant creation or applied convergence. |
Discover base permissions and every organization role and assignment. Accept owners as desired users, defer ambiguous owner grants and roles below inherited access, and preserve organization/enterprise team sources using access_source. Refresh organization access for stale-plan and convergence checks, fail closed on incomplete metadata, and document required read permissions and policy exceptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8107bce-2500-45f8-b046-3f50092d9fbd
| @@ -0,0 +1,86 @@ | |||
| # frozen_string_literal: true | |||
There was a problem hiding this comment.
Organization grants will show up in the access list for the Repository. Because the API represents your highest level of highest issued access, we need to reconcile who has access from Organization access, or we will try and fail to add Org Administrators to any repo they are given a direct entitlement for. This is also in play during JIT access, complicating matters even more, as in some runs a user will appear as a Repository Owner issued as an Organization grant and in other runs they will have their normal individually issued access.


This pull request adds support for GitHub repositories as a "backend" for the GitHub plugin.
One of the most noteworthy parts of this pull request is that it supports using a GH App as the credential, which can be supplied separately in the configuration.
I'll fill in this PR body with additional details, but for more information, see the README.md modifications in the PR.